package com.wn.icloud.plugin;

import com.google.common.collect.Lists;
import com.wn.icloud.plugin.generator.CodeCopier;
import com.wn.icloud.plugin.generator.CodeGenerator;
import com.wn.icloud.plugin.util.JdlUtil;
import org.apache.commons.io.FileUtils;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author kyy
 * @date 2018/12/03
 */
@Mojo(name = "GenBackendCode", defaultPhase = LifecyclePhase.NONE)
public class GenBackendCodeMojo extends AbstractMojo {


    @Parameter(property = "basePackage", required = true)
    private String basePackage;

    @Parameter(property = "mavenModuleName", required = true)
    private String mavenModuleName;

    @Parameter(property = "moduleName", required = true)
    private String moduleName;


    @Parameter(defaultValue = "jdl",
            property = "jdlFilePath", required = false)
    private String jdlFilePath;

    @Parameter(defaultValue = "false",
            property = "overWrite", required = false)
    private Boolean overWrite;

    @Parameter(defaultValue = "10",
            property = "timeOut", required = false)
    private Long timeOut;

    @Parameter(property = "noOverWriteDomain", required = false)
    private List<String> noOverWriteDomain = Lists.newArrayList();

    private CodeGenerator codeGenerator;

    private CodeCopier codeCopier;


    public GenBackendCodeMojo() {
        super();
    }


    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {

        System.out.println(noOverWriteDomain);

        this.codeGenerator = new CodeGenerator(mavenModuleName, basePackage, moduleName);
        this.codeCopier = new CodeCopier(mavenModuleName, basePackage, moduleName);

        codeGenerator.setOverwrite(overWrite);
        codeGenerator.setNoOverWriteDomain(noOverWriteDomain);

        String rootPath = System.getProperty("user.dir");
        getLog().info("===========rootPath:" + rootPath + "=============");
        getLog().info("===========basePackage:" + basePackage + "=============");
        getLog().info("===========mavenModuleName:" + mavenModuleName + "=============");
        getLog().info("===========moduleName:" + moduleName + "=============");
        getLog().info("===========jdlFilePath:" + jdlFilePath + "=============");
        getLog().info("===========overWrite:" + overWrite + "=============");

        // 保存service
        codeGenerator.storeFile();
        // 解析jdl文件，并生成代码,这里只使用生成的domain、service.dto、service.mapper
        Collection<File> jdlFiles = FileUtils
                .listFiles(new File(jdlFilePath), new String[]{"jdl"}, true);
        if (JdlUtil.genCodeFormJdl(jdlFiles, timeOut) == false) {
            getLog().warn("根据jdl文件生成代码错误");
        }
        // 删除生成的 repository、service、web
        // 复原service
        // 修改domain基类
         codeGenerator.restoreFile();

        // 根据jdl里定义的实体生成对应的dao、service、serviceImpl、controller
        jdlFiles.forEach(this::genCodeForJdlFile);
    }


    /**
     * 根据jdl生成代码
     *
     * @param jdlFile jdl文件
     */
    private void genCodeForJdlFile(File jdlFile) {
        getLog().info("gen util for file:" + jdlFile.getName());
        List<String> lines = null;
        try {
            lines = FileUtils.readLines(jdlFile, "utf-8");
        } catch (IOException e) {
            getLog().error(e);
            return;
        }
        lines.stream()
                .map(this::getEntityName)
                .filter(Objects::nonNull)
                .forEach(domain -> {
                    getLog().info("gen code for entity:" + domain);
                    try {
                        codeGenerator.genCode("dao", domain);
                        codeGenerator.genCode("service", domain);
                        codeGenerator.genCode("service.impl", domain);
                        codeGenerator.genCode("controller", domain);
                    } catch (Exception e) {
                        getLog().error(e);
                    }
                });
    }

    private Pattern entityPattern = Pattern.compile("(?<=^entity[\\s+])\\w+");

    private String getEntityName(String line) {
        Matcher matcher = entityPattern.matcher(line);
        boolean rs = matcher.find();
        if (rs) {
            String group = matcher.group();
            return group;
        }
        return null;
    }

}
